<template>
  <div class="productcenter-container">
    <!-- 面包屑 -->
    <div class="bread">
      <el-breadcrumb separator="/" style="border:none;">
        <!-- <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> -->
        <el-breadcrumb-item>产品中心</el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    <el-card :body-style="{ padding: '15px' }">
      <!-- 标签页 -->
      <div class="tab">
        <el-tabs v-model="currentPlatform">
          <el-tab-pane v-for="(i,j) in tagsData" :key="j" :label="i.name" :name="`${i.id}`">
            <el-card class="category-card" :body-style="{ padding: '15px' }" shadow="never">
              <el-button
                @click="changeCategory(i.id,m.id,1)"
                v-for="(m,n) in i.category_usable"
                :key="n"
                plain
                :loading="platformId==i.id&&categoryId==m.id&&productlistDataLoading"
              >{{platformId==i.id&&categoryId==m.id&&productlistDataLoading?'加载中 ...':m.name}}</el-button>
            </el-card>
          </el-tab-pane>
        </el-tabs>
        <!-- Productlist.vue -->
        <productlist style="margin-top:15px;" :data="activeData" :loading="productlistDataLoading"></productlist>
        <!-- 页码 -->
        <div class="pages">
          <el-pagination
            background
            :current-page.sync="currentPage"
            :page-size="pageSize"
            layout="total, prev, pager, next"
            :total="totalNumber"
            @current-change="changePage"
          ></el-pagination>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script>
import platformjson from '../../../../lib/platform.json'
import categoryjson from '../../../../lib/category.json'
import Productlist from '../Productcenter/Productlist'
export default {
  data() {
    return {
      tagsData: platformjson, // [渲染数据]
      productlistData: [], // [内部数据] 包含所有已请求的数据
      productlistDataLoading: true, // [内部数据] [标志] 路由参数更新时是否调用loadProductList的标志
      activeData: [], // [渲染数据] 用于展示数据
      platformId: 0, // [请求参数]
      categoryId: 0, // [请求参数]
      pageSize: 6, // [请求参数]
      currentPlatform: '0', // [组件属性] 平台标签页索引
      currentPage: 1, // [组件属性] 当前页码
      activePage: 0, // [请求参数] 用于防止快速点击造成的重复请求
      totalNumber: 0 // [渲染数据] 因总条数来源于异步数据而无法直接获取而设立的值
    }
  },
  methods: {
    // 更新当前路由参数数据，为翻页时发送请求提供参数,同时也被用于防止快速点击造成的重复请求
    setParams(pid, cid, pg) {
      this.platformId = +pid
      this.categoryId = +cid
      this.activePage = +pg
    },
    // 用于请求预览数据的方法,会将获取到的数据保存进productlistData数组
    getProductList(pid, cid, pg) {
      return new Promise((resolve, reject) => {
        // 第一层if语句是为了防止快速点击造成的重复请求
        this.axios
          .get(`/myserver/productlist/${pid}/${cid}/${pg}/${this.pageSize}/`)
          .then(res => {
            // 给图片的地址添加前缀
            // 可优化项：多个场景中都涉及了图片地址添加前缀，可将方法保存进vuex
            res.data.data.forEach(i => {
              i.image.forEach((o, p, q) => {
                q[p] = this.API.myserver + o
              })
            })
            this.activeData = res.data.data
            this.productlistData[pid][cid][pg - 1] = res.data
            this.totalNumber = this.productlistData[pid][cid][pg - 1].total
            localStorage.setItem(
              'productlistData',
              JSON.stringify(this.productlistData)
            )
            resolve()
          })
      })
    },
    // 非页面元素调用的用于请求和展示预览数据的方法，getProductList的封装，因调用者的缘故需要传入一个$route对象（调用者：create，beforeRouteUpdate）
    loadProductList(req) {
      // 初始化productlistData数组，当三个维度的数据为空时认定当前要获取的productlistData数据不存在
      if (this.productlistData == null) {
        this.productlistData = []
      }
      if (this.productlistData[req.params.platformId] == null) {
        this.productlistData[req.params.platformId] = []
      }
      if (
        this.productlistData[req.params.platformId][req.params.categoryId] ==
        null
      ) {
        this.productlistData[req.params.platformId][req.params.categoryId] = []
      }
      if (
        this.productlistData[req.params.platformId][req.params.categoryId][
          req.params.page - 1
        ] == null
      ) {
        // 预览数据不存在时调用getProductList进行请求，再改变平台标签页索引和页码
        this.getProductList(
          req.params.platformId,
          req.params.categoryId,
          req.params.page,
          this.pageSize
        ).then(() => {
          this.currentPlatform = req.params.platformId
          this.currentPage = +req.params.page
          this.setParams(
            req.params.platformId,
            req.params.categoryId,
            req.params.page
          )
          this.productlistDataLoading = false
        })
      } else {
        // 预览数据已存在时直接展示数据，并只改变平台标签页索引和页码
        this.activeData = this.productlistData[req.params.platformId][
          req.params.categoryId
        ][req.params.page - 1].data
        this.totalNumber = this.productlistData[req.params.platformId][
          req.params.categoryId
        ][req.params.page - 1].total
        this.currentPlatform = req.params.platformId
        this.currentPage = +req.params.page
        this.setParams(
          req.params.platformId,
          req.params.categoryId,
          req.params.page
        )
        this.productlistDataLoading = false
      }
    },
    // 页面元素间接调用的用于请求和展示预览数据的方法，loadProductList的包装（调用者：分类按钮，页码按钮）
    reloadProductlist(pid, cid, pg) {
      if (
        this.platformId !== pid ||
        this.categoryId !== cid ||
        this.activePage !== pg
      ) {
        // 由于reloadProductlist被页面元素调用，同时内部又涉及请求方法getProductList，所以快速点击时会造成重复请求,因此要立即调用setParams方法
        this.setParams(pid, cid, pg)
        // productlistData数组中任意一个维度的数组为null则说明当前预览数据暂未获取
        if (
          this.productlistData[pid] == null ||
          this.productlistData[pid][cid] == null ||
          this.productlistData[pid][cid][pg - 1] == null
        ) {
          // productlistDataLoading作为路由参数更新时（beforeRouteUpdate）是否调用loadProductList的标志必须在路由更新前修改，即必须位于this.$router.push语句前
          this.productlistDataLoading = true
        } else {
          // 预览数据已存在时直接从productlistData中获取并展示
          this.activeData = this.productlistData[pid][cid][pg - 1].data
          this.totalNumber = this.productlistData[pid][cid][pg - 1].total
        }
        // this.$router.push更新时若reloadProductlist为false，则只对浏览器的路由显示进行修改；而为true，则会触发beforeRouteUpdate中的loadProductList
        this.$router.push({
          path: `/user/productcenter/${pid}/${cid}/${pg}`
        })
      } else {
        if (this.currentPlatform === `${pid}`) {
          this.$message('正处在该平台分类中')
        } else {
          this.currentPlatform = `${pid}`
        }
      }
    },
    changePlatform(pid, cid) {
      this.reloadProductlist(pid, cid, 1)
      this.currentPage = 1
    },
    changeCategory(pid, cid, pg) {
      this.reloadProductlist(pid, cid, pg)
      this.currentPage = 1
    },
    changePage(newPage) {
      this.reloadProductlist(this.platformId, this.categoryId, newPage)
    }
  },
  components: {
    productlist: Productlist
  },
  created() {
    // 先从本地存储获取productlistData数据
    this.productlistData = JSON.parse(localStorage.getItem('productlistData'))
    this.loadProductList(this.$route)
    // 初始化标签页渲染数据
    this.tagsData.forEach(i => {
      i.category_usable.forEach((m, n) => {
        for (var o in categoryjson) {
          if (categoryjson[o].id === +m) {
            i.category_usable[n] = categoryjson[o]
          }
        }
      })
    })
  },
  mounted() {
    // 只能用于productcenter路由下产品列表的加载
    this.Emit.$on('changePlatform', (pid, cid) => {
      this.changePlatform(pid, cid)
    })
  },
  // 已优化项：不刷新页面的页面更新
  beforeRouteUpdate(to, from, next) {
    this.productlistDataLoading = true
    this.loadProductList(to)
    next()
  },
  destroyed() {
    this.Emit.$off('changePlatform')
  }
}
</script>

<style lang="less" scope>
.productcenter-container {
  .bread {
    padding: 20px 0;
  }
  .pages {
    margin: 10px 0;
    display: flex;
    justify-content: center;
  }
}
</style>
